#version 120

uniform sampler2D backfacetexture;
uniform sampler3D volumetexture;
uniform sampler3D crackedVolume;

uniform sampler1D tranf;

uniform float stepsize;
uniform float begin;
uniform float isoValue;

varying vec4 vposition;
varying vec3 eposition;
uniform vec4 lightposition;


const float shininess = 5;
const float diffuse = 0.0;
const float specular = 1.0;

vec3 map260to258(vec3 cood)
{
	vec3 offsetGL = vec3(0.5/258.0);
	vec3 ocood = cood*(258.0/260.0);
	return offsetGL+257.0/258.0*ocood;	
}

vec3 textureOffset(vec3 cood)
{
	vec3 offsetGL = vec3(0.5/260.0);
	return offsetGL+259.0/260.0*cood;	

}

float rand(vec2 co)
{        
	return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453) / 200;        
} 

float offset(vec2 xy)
{
	return fract((xy.x)*1.298/1000+(xy.y)/1000)/80;
}

vec4 DirectVolumeRendering(vec3 front, vec3 back, float upperThreshold, float threshold, float offset)
{
	vec3 dir;
	dir = back - front;
	float len = length(dir);
	vec3 norm_dir = normalize(dir);
	//float iso_value = 0.1;

	vec3 rayIncrement = stepsize*norm_dir;

	vec3 pos = front;
	vec4 value=vec4(0,0,0,0);
	// accumlate value
	vec4 result = vec4(0,0,0,0);//RGBA
	float raylength = 0;

    float scale = 1.0/(upperThreshold - threshold);
    float res = 0;
    
	for(int i=0; i<1000; i++)
	{
		float factor = 0.5;
		if(pos.x < 0.5 && pos.y < 0.5 && pos.z < 0.5)
		{
				vec3 offsetBlock = vec3(factor);
//				value = texture3D(volumetexture, offsetBlock+ 0.5/258.0 + 0.5*128.0/129.0*(pos)  );
if(isoValue>0.1)
				value = texture3D(volumetexture,    0.5/258.0+ 128.0/129.0*pos  );
else
				value = texture3D(crackedVolume,    0.5/258.0+ 128.0/129.0*pos  );

				//value = vec4(0,0,0,0);
		}
		else 
		{
				vec3 offsetBlock = vec3(factor);
if(isoValue>0.1)
				value = texture3D(volumetexture, offsetBlock+ 0.5/258.0 + 0.5*128.0/129.0*(pos)  );
else
				value = texture3D(crackedVolume, offsetBlock+ 0.5/258.0 + 0.5*128.0/129.0*(pos)  );
				
				//value = vec4(0,0,0,0);
		//pos += rayIncrement*0.5;
		}
		pos += rayIncrement;
		
		//value = texture3D(volumetexture, 0.75*(pos)+vec3(0.5/4.0));
	
		raylength += length(rayIncrement);

			vec4 texValue = texture1D(tranf, value.a);

			result.rgb += (1.0-result.a)*texValue.a*texValue.rgb;
			result.a += (1.0-result.a)*texValue.a;

			if (result.a >= 0.9 || raylength > len ) 
			{
				break;
			}
	}
	return result;

}

void main()
{
	vec2 texposition = ((vposition.xy/vposition.w) + 1.0)/2.0;
	//interleave sampling pattern========================================
	float w=800;
	float h=800;
	vec2 interleavePosf = vec2(texposition.x*w, texposition.y*h);
	ivec2 interleavePos;
	interleavePos.x = int(floor(interleavePosf.x + 0.5));
	interleavePos.y = int(floor(interleavePosf.y + 0.5));

	interleavePos.x = int(mod(interleavePos.x,8));
	interleavePos.y = int(mod(interleavePos.y,8));
	float offset = offset(interleavePos);	
	//===================================================================

	vec3 start = gl_TexCoord[0].xyz;
	vec3 backposition = texture2D(backfacetexture, texposition).rgb;

	float upperThreshold = 1.0;
	float threshold = 0.1;
	vec4 result = DirectVolumeRendering(start, backposition, upperThreshold, threshold, offset);
	gl_FragColor = (1-result.a)*vec4(0.2, 0.2, 0.2, 1) + result.a * result;


}
